#pragma once
#include <iostream>
#include <string>
#include <strings.h>
#include <cerrno>
#include <cstring>
#include <cstdlib>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <pthread.h>

using namespace std;

namespace udpClient
{
class udpclient
{

public:

udpclient(const string& ip,const uint16_t port)
:_serverip(ip)
,_serverport(port)
,_sockfd(-1)
,flag(false)
{}

void initclient()
{
    //1.创建套接字
    _sockfd=socket(AF_INET,SOCK_DGRAM,0);
    if(_sockfd==-1)
    {
        cout<<"socket error"<<errno<<":"<<strerror(errno)<<endl;
        exit(2);
    }
    cout<<"socket success: "<<_sockfd<<endl;
    //2.绑定，但不用显示绑定，OS会自动绑定指定ip和端口
}

static void* readmessage(void* args)
{
    int sockfd=*(static_cast<int*>(args));

    pthread_detach(pthread_self());//线程退出自动释放资源
    while(true)
    {
        char buffer[1024];
    struct sockaddr_in tmp;
    socklen_t len=sizeof(tmp);
    ssize_t n=recvfrom(sockfd,buffer,sizeof(buffer),0,(struct sockaddr*)&tmp,&len);
    if(n>0)
    {
        buffer[n]=0;
        cout<<buffer<<endl;
    }
    }
    return nullptr;
}

void run()
{
    pthread_create(&_pt,nullptr,readmessage,(void*)&_sockfd);

    struct sockaddr_in server;
    server.sin_family=AF_INET;
    server.sin_addr.s_addr=inet_addr(_serverip.c_str());
    server.sin_port=htons(_serverport);

    string message;
    char cmdbuffer[1024];
    while(!flag)
    {
        fprintf(stderr,"enter# ");
        fflush(stderr);
        fgets(cmdbuffer,sizeof(cmdbuffer),stdin);//键盘上的内容写入缓冲区cmdbuffer
        cmdbuffer[strlen(cmdbuffer)-1]=0;
        message=cmdbuffer;
        sendto(_sockfd,message.c_str(),message.size(),0,(struct sockaddr*)&server,sizeof(server));
        //将缓冲区的内容发送带套接字里通常用于UDP
    }
}

~udpclient(){}



private:
int _sockfd;
string _serverip;
uint16_t _serverport;
bool flag;
pthread_t _pt;
};


}

